package cn.itcast.nems.employee.service.impl;

import cn.itcast.ic.common.bean.Page;
import cn.itcast.nems.base.api.SchoolApi;
import cn.itcast.nems.base.api.SubjectApi;
import cn.itcast.nems.base.dto.SchoolDTO;
import cn.itcast.nems.base.dto.SubjectDTO;
import cn.itcast.nems.common.PageQueryModel;
import cn.itcast.nems.common.account.AccountHolder;
import cn.itcast.nems.common.entity.UUIDEntity;
import cn.itcast.nems.common.tenant.TenantInfo;
import cn.itcast.nems.employee.dao.bean.EmployeeGroupBean;
import cn.itcast.nems.employee.dao.bean.EmployeeGroupsBean;
import cn.itcast.nems.employee.bo.*;
import cn.itcast.nems.employee.dao.condition.EmployeeGroupCondition;
import cn.itcast.nems.employee.dao.entity.*;
import cn.itcast.nems.employee.dao.mapper.EmployeeGroupMapper;
import cn.itcast.nems.employee.dao.mapper.EmployeeGroupMemberMapper;
import cn.itcast.nems.employee.dao.mapper.EmployeeGroupSchoolMapper;
import cn.itcast.nems.employee.dao.mapper.EmployeeGroupSubjectMapper;
import cn.itcast.nems.employee.dto.*;
import cn.itcast.nems.employee.service.EmployeeGroupService;
import cn.itcast.nems.employee.service.EmployeeService;
import cn.itcast.nems.manager.msas.MsasManager;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itcast.msas.sdk.acm.domain.AccountResourceDto;
import com.itcast.msas.sdk.acm.domain.Role;
import com.itcast.msas.sdk.usr.domain.MsasUser;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class EmployeeGroupServiceImpl implements EmployeeGroupService {

    private final SubjectApi subjectApi;
    private final SchoolApi schoolApi;

    private final EmployeeGroupMapper employeeGroupMapper;
    private final EmployeeGroupMemberMapper employeeGroupMemberMapper;
    private final EmployeeGroupSubjectMapper employeeGroupSubjectMapper;
    private final EmployeeGroupSchoolMapper employeeGroupSchoolMapper;

    private final EmployeeService employeeService;

    private final MsasManager msasManager;

    @Override
    public EmployeeGroupDto findEmployeeGroupById(String id) {
        var group = employeeGroupMapper.selectById(id);
        if (group == null) {
            return null;
        }
        return mapPage(List.of(group)).get(0);
    }

    @Override
    public Page<EmployeeGroupDto> findEmployeeGroupPageList(PageQueryModel<EmployeeGroupQueryDto> queryModel) {
        IPage<EmployeeGroup> page = employeeGroupMapper.selectPageData(
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<EmployeeGroup>()
                        .setCurrent(queryModel.getPageNumber())
                        .setSize(queryModel.getPageSize()),
                new ObjectMapper().convertValue(
                        queryModel.getCondition(),
                        EmployeeGroupCondition.class
                )
        );
        return mapPage(page);
    }

    private Page<EmployeeGroupDto> mapPage(IPage<EmployeeGroup> page) {
        return Page.of(
                (int) page.getCurrent(),
                (int) page.getSize(),
                (int) page.getTotal(),
                mapPage(page.getRecords())
        );
    }

    private List<EmployeeGroupDto> mapPage(List<EmployeeGroup> records) {
        if (records == null) {
            return null;
        }
        if (records.isEmpty()) {
            return List.of();
        }
        var groupIdSet = records.stream().map(EmployeeGroup::getId).collect(Collectors.toSet());
        var groupSubjects = employeeGroupSubjectMapper.selectList(new QueryWrapper<EmployeeGroupSubject>()
                .lambda()
                .in(EmployeeGroupSubject::getGroupId, groupIdSet)
                .eq(EmployeeGroupSubject::getDeletedFlag, Boolean.FALSE)
        );
        var groupSubjectMap = groupSubjects.stream().collect(Collectors.groupingBy(EmployeeGroupSubject::getGroupId));
        var subjectIdSet = groupSubjects.stream().map(EmployeeGroupSubject::getSubjectId).collect(Collectors.toSet());
        var subjectMap = subjectIdSet.isEmpty() ? new HashMap<String, SubjectDTO>() : subjectApi.findListByIds(subjectIdSet).stream().collect(Collectors.toMap(
                SubjectDTO::getId,
                i -> i
        ));
        var groupSchools = employeeGroupSchoolMapper.selectList(new QueryWrapper<EmployeeGroupSchool>()
                .lambda()
                .in(EmployeeGroupSchool::getGroupId, groupIdSet)
                .eq(EmployeeGroupSchool::getDeletedFlag, Boolean.FALSE)
        );
        var groupSchoolMap = groupSchools.stream().collect(Collectors.groupingBy(EmployeeGroupSchool::getGroupId));
        var schoolMap = schoolApi.getAllLogicSchool().stream().collect(Collectors.toMap(
                SchoolDTO::getCode,
                i -> i
        ));
        return records.stream()
                .map(item -> {
                    var dto = new EmployeeGroupDto();
                    dto.setId(item.getId());
                    dto.setName(item.getName());
                    String createdBy = item.getCreatedBy();
                    String modifiedBy = item.getModifiedBy();
                    dto.setCreatedBy(createdBy);
                    dto.setCreatedDatetime(item.getCreatedDatetime());
                    dto.setModifiedBy(modifiedBy);
                    dto.setModifiedDatetime(item.getModifiedDatetime());
                    Employee employeeCreated = employeeService.findOneByEmail(createdBy);
                    dto.setCreatedName(Objects.nonNull(employeeCreated) ? employeeCreated.getName() : createdBy);
                    dto.setCreatedByName(Objects.nonNull(employeeCreated) ? employeeCreated.getName() + "（" + employeeCreated.getEmail() + "）" : createdBy);
                    Employee employeeModified = employeeService.findOneByEmail(modifiedBy);
                    dto.setModifieName(Objects.nonNull(employeeModified) ? employeeModified.getName() : modifiedBy);
                    dto.setModifieByName(Objects.nonNull(employeeModified) ? employeeModified.getName() + "（" + employeeModified.getEmail() + "）" : modifiedBy);
                    dto.setSubjectList(groupSubjectMap.getOrDefault(item.getId(), new ArrayList<>()).stream().map(i -> subjectMap.get(i.getSubjectId())).filter(Objects::nonNull).collect(Collectors.toList()));
                    dto.setSchoolList(groupSchoolMap.getOrDefault(item.getId(), new ArrayList<>()).stream().map(i -> schoolMap.get(i.getSchoolCode())).filter(Objects::nonNull).collect(Collectors.toList()));
                    return dto;
                })
                .toList();
    }

    @Getter
    @AllArgsConstructor
    private static class CheckResult {
        private String name;
        private List<SchoolDTO> schools;
        private List<SubjectDTO> subjects;
        private String userAccount;
    }

    private CheckResult checkBo(EmployeeGroupBo bo) {
        Assert.hasText(bo.getName(), "用户组名称不能为空");
        Assert.notNull(bo.getSchoolCodeList(), "您至少要选择一个校区");
        Assert.isTrue(!bo.getSchoolCodeList().isEmpty(), "您至少要选择一个校区");
        Assert.notNull(bo.getSubjectIdList(), "您至少要选择一个学科");
        Assert.isTrue(!bo.getSubjectIdList().isEmpty(), "您至少要选择一个学科");
        var subjects = subjectApi.findListByIds(bo.getSubjectIdList());
        var schools = schoolApi.getAllLogicSchool().stream().filter(i -> bo.getSchoolCodeList().contains(i.getCode())).toList();
        Assert.isTrue(bo.getSchoolCodeList().size() == schools.size(), "您选择的校区未找到");
        Assert.isTrue(bo.getSubjectIdList().size() == subjects.size(), "您选择的学科未找到");
        var userAccount = AccountHolder.getRequiredAccountInfo().getEmail();
        return new CheckResult(bo.getName(), schools, subjects, userAccount);
    }

    @Override
    @Transactional
    public boolean createEmployeeGroup(EmployeeGroupCreateBo _bo) {
        var checkResult = checkBo(_bo);
        var name = checkResult.getName();
        var schools = checkResult.getSchools();
        var subjects = checkResult.getSubjects();
        var userAccount = checkResult.getUserAccount();
        var now = LocalDateTime.now();
        EmployeeGroup employeeGroup = new EmployeeGroup();
        employeeGroup.setName(name);
        initCommonField(employeeGroup, userAccount, now);
        employeeGroupMapper.insert(employeeGroup);
        var groupId = employeeGroup.getId();
        schools.forEach(i -> addSchools(groupId, i, userAccount, now));
        subjects.forEach(i -> addSubjects(groupId, i, userAccount, now));
        return true;
    }

    private void initCommonField(UUIDEntity uuidEntity, String userAccount, LocalDateTime now) {
        uuidEntity.setTenantId(TenantInfo.DEFAULT_TENANT_ID);
        uuidEntity.setSubtenantId(TenantInfo.DEFAULT_SUBTENANT_ID);
        uuidEntity.setCreatedBy(userAccount);
        uuidEntity.setCreatedDatetime(now);
        uuidEntity.setModifiedBy(userAccount);
        uuidEntity.setModifiedDatetime(now);
        uuidEntity.setDeletedFlag(Boolean.FALSE);
    }

    private void addSchools(String groupId, SchoolDTO i, String userAccount, LocalDateTime now) {
        var item = new EmployeeGroupSchool();
        item.setGroupId(groupId);
        item.setSchoolCode(i.getCode());
        item.setSchoolName(i.getName());
        initCommonField(item, userAccount, now);
        employeeGroupSchoolMapper.insert(item);
    }

    private void addSubjects(String groupId, SubjectDTO i, String userAccount, LocalDateTime now) {
        var item = new EmployeeGroupSubject();
        item.setGroupId(groupId);
        item.setSubjectId(i.getId());
        item.setSubjectName(i.getName());
        initCommonField(item, userAccount, now);
        employeeGroupSubjectMapper.insert(item);
    }

    @Override
    @Transactional
    public boolean updateEmployeeGroup(EmployeeGroupUpdateBo _bo) {
        var checkResult = checkBo(_bo);
        var id = _bo.getId();
        var name = checkResult.getName();
        var schools = checkResult.getSchools();
        var subjects = checkResult.getSubjects();
        var userAccount = checkResult.getUserAccount();
        Assert.hasText(id, "要修改的用户组ID不能为空");
        var group = employeeGroupMapper.selectOne(new QueryWrapper<EmployeeGroup>()
                .lambda()
                .eq(EmployeeGroup::getId, id)
                .eq(EmployeeGroup::getDeletedFlag, Boolean.FALSE));
        Assert.notNull(group, "要修改的用户组不存在");
        var groupSubjects = employeeGroupSubjectMapper.selectList(new QueryWrapper<EmployeeGroupSubject>()
                .lambda()
                .eq(EmployeeGroupSubject::getGroupId, id)
                .eq(EmployeeGroupSubject::getDeletedFlag, Boolean.FALSE)
        );
        var groupSchools = employeeGroupSchoolMapper.selectList(new QueryWrapper<EmployeeGroupSchool>()
                .lambda()
                .eq(EmployeeGroupSchool::getGroupId, id)
                .eq(EmployeeGroupSchool::getDeletedFlag, Boolean.FALSE)
        );
        var finalSchoolCodes = schools.stream().map(SchoolDTO::getCode).collect(Collectors.toSet());
        var finalSubjectIds = subjects.stream().map(SubjectDTO::getId).collect(Collectors.toSet());
        var inDbSchoolCodes = groupSchools.stream().map(EmployeeGroupSchool::getSchoolCode).collect(Collectors.toSet());
        var inDbSubjectIds = groupSubjects.stream().map(EmployeeGroupSubject::getSubjectId).collect(Collectors.toSet());
        var removeSchoolCodes = inDbSchoolCodes.stream().filter(i -> !finalSchoolCodes.contains(i)).toList();
        var removeSubjectIds = inDbSubjectIds.stream().filter(i -> !finalSubjectIds.contains(i)).toList();
        var addSchools = schools.stream().filter(i -> !inDbSchoolCodes.contains(i.getCode())).toList();
        var addSubjects = subjects.stream().filter(i -> !inDbSubjectIds.contains(i.getId())).toList();
        var now = LocalDateTime.now();
        employeeGroupMapper.update(null, new UpdateWrapper<EmployeeGroup>()
                .lambda()
                .eq(EmployeeGroup::getId, id)
                .set(EmployeeGroup::getName, name)
                .set(EmployeeGroup::getModifiedBy, userAccount)
                .set(EmployeeGroup::getModifiedDatetime, now));
        if (!removeSchoolCodes.isEmpty()) {
            employeeGroupSchoolMapper.update(null, new UpdateWrapper<EmployeeGroupSchool>()
                    .lambda()
                    .eq(EmployeeGroupSchool::getGroupId, id)
                    .eq(EmployeeGroupSchool::getDeletedFlag, Boolean.FALSE)
                    .in(EmployeeGroupSchool::getSchoolCode, removeSchoolCodes)
                    .set(EmployeeGroupSchool::getDeletedFlag, Boolean.TRUE));
        }
        if (!removeSubjectIds.isEmpty()) {
            employeeGroupSubjectMapper.update(null, new UpdateWrapper<EmployeeGroupSubject>()
                    .lambda()
                    .eq(EmployeeGroupSubject::getGroupId, id)
                    .eq(EmployeeGroupSubject::getDeletedFlag, Boolean.FALSE)
                    .in(EmployeeGroupSubject::getSubjectId, removeSubjectIds)
                    .set(EmployeeGroupSubject::getDeletedFlag, Boolean.TRUE));
        }
        addSchools.forEach(i -> addSchools(id, i, userAccount, now));
        addSubjects.forEach(i -> addSubjects(id, i, userAccount, now));
        return true;
    }

    @Override
    public boolean deleteEmployeeGroup(String id) {
        var userAccount = AccountHolder.getRequiredAccountInfo().getEmail();
        var now = LocalDateTime.now();
        employeeGroupMapper.update(null, new UpdateWrapper<EmployeeGroup>()
                .lambda()
                .eq(EmployeeGroup::getId, id)
                .set(EmployeeGroup::getDeletedBy, userAccount)
                .set(EmployeeGroup::getDeletedDatetime, now)
                .set(EmployeeGroup::getDeletedFlag, Boolean.TRUE));
        return true;
    }

    @Override
    public Page<EmployeeInGroupDto> findEmployeeFromGroupPageList(PageQueryModel<EmployeeFromGroupQueryDto> queryModel) {
        var page = employeeGroupMemberMapper.selectPage(
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<EmployeeGroupMember>()
                        .setCurrent(queryModel.getPageNumber())
                        .setSize(queryModel.getPageSize()),
                new QueryWrapper<EmployeeGroupMember>()
                        .lambda()
                        .eq(EmployeeGroupMember::getGroupId, queryModel.getCondition().getGroupId())
                        .like(StringUtils.hasText(queryModel.getCondition().getAccountLike()), EmployeeGroupMember::getEmployeeAccount, queryModel.getCondition().getAccountLike())
                        .eq(EmployeeGroupMember::getDeletedFlag, Boolean.FALSE)
                        .orderByDesc(EmployeeGroupMember::getCreatedDatetime)
        );
        return mapMemberPage(page);
    }

    private Page<EmployeeInGroupDto> mapMemberPage(IPage<EmployeeGroupMember> page) {
        return Page.of(
                (int) page.getCurrent(),
                (int) page.getSize(),
                (int) page.getTotal(),
                mapMemberPage(page.getRecords())
        );
    }

    private List<EmployeeInGroupDto> mapMemberPage(List<EmployeeGroupMember> records) {
        if (records == null) {
            return null;
        }
        if (records.isEmpty()) {
            return List.of();
        }
        var set = records.stream().map(EmployeeGroupMember::getEmployeeAccount).collect(Collectors.toSet());
        final var employeeMap = msasManager.findEmployees(set)
                .stream()
                .collect(Collectors.toMap(
                        MsasUser::getEmail,
                        i -> i
                ));
        final var accountMetadataMap = msasManager.findAccountMetadata(set)
                .stream()
                .collect(Collectors.toMap(
                        AccountResourceDto::getAccount,
                        i -> i
                ));
        var rm = msasManager.findRolesMetadata()
                .stream()
                .collect(Collectors.toMap(
                        Role::getCode,
                        i -> i
                ));
        return records.stream().map(i -> {
            var employee = employeeMap.get(i.getEmployeeAccount());
            var metadata = accountMetadataMap.get(i.getEmployeeAccount());
            var dto = new EmployeeInGroupDto();
            dto.setEmail(i.getEmployeeAccount());
            if (employee != null) {
                dto.setName(employee.getCn());
                dto.setJobNumber(employee.getEmployeeNumber());
                dto.setPositionName(employee.getTitle());
                dto.setDepartmentName(employee.getDepartmentName());
                dto.setJoinTime(i.getCreatedDatetime());
            }
            setRoleNameJoin(dto, metadata, rm);
            dto.setNameAndEmail(
                    (StringUtils.hasText(dto.getName()) ? dto.getName() : "")
                            + "(" + dto.getEmail() + ")"
            );
            return dto;
        }).toList();
    }

    @Override
    @Transactional
    public boolean addEmployeeToGroup(AddEmployeeToGroupBo bo) {
        Assert.hasText(bo.getGroupId(), "用户组ID不能为空");
        Assert.notNull(bo.getEmployeeAccountList(), "您至少要选择一个用户");
        Assert.isTrue(!bo.getEmployeeAccountList().isEmpty(), "您至少要选择一个用户");
        var group = employeeGroupMapper.selectOne(new QueryWrapper<EmployeeGroup>()
                .lambda()
                .eq(EmployeeGroup::getId, bo.getGroupId())
                .eq(EmployeeGroup::getDeletedFlag, Boolean.FALSE));
        Assert.notNull(group, "用户组不存在");
        var set = bo.getEmployeeAccountList().stream().collect(Collectors.toSet());
        var find = msasManager.findEmployees(set);
        Assert.isTrue(find.size() == set.size(), "您选择的用户未找到");
        var exists = employeeGroupMemberMapper.selectList(new QueryWrapper<EmployeeGroupMember>()
                .lambda()
                .eq(EmployeeGroupMember::getGroupId, bo.getGroupId())
                .eq(EmployeeGroupMember::getDeletedFlag, Boolean.FALSE)
                .in(EmployeeGroupMember::getEmployeeAccount, set)
        ).stream().map(EmployeeGroupMember::getEmployeeAccount).collect(Collectors.toSet());
        var notExists = find.stream().filter(i -> !exists.contains(i.getEmail())).toList();
        if (notExists.isEmpty()) {
            Assert.isTrue(false, "用户已经存在于用户组");
            return true;
        }
        var now = LocalDateTime.now();
        var userAccount = AccountHolder.getRequiredAccountInfo().getEmail();
        for (MsasUser notExist : notExists) {
            addMember(group.getId(), notExist.getEmail(), userAccount, now);
        }
        return true;
    }

    private void addMember(String groupId, String account, String userAccount, LocalDateTime now) {
        var item = new EmployeeGroupMember();
        item.setGroupId(groupId);
        item.setEmployeeAccount(account);
        initCommonField(item, userAccount, now);
        employeeGroupMemberMapper.insert(item);
    }

    @Override
    public boolean deleteEmployeeFromGroup(DeleteEmployeeFromGroupBo bo) {
        Assert.hasText(bo.getGroupId(), "用户组ID不能为空");
        Assert.notNull(bo.getEmployeeAccountList(), "您至少要选择一个用户");
        Assert.isTrue(!bo.getEmployeeAccountList().isEmpty(), "您至少要选择一个用户");
        var group = employeeGroupMapper.selectOne(new QueryWrapper<EmployeeGroup>()
                .lambda()
                .eq(EmployeeGroup::getId, bo.getGroupId())
                .eq(EmployeeGroup::getDeletedFlag, Boolean.FALSE));
        Assert.notNull(group, "用户组不存在");
        var set = bo.getEmployeeAccountList().stream().collect(Collectors.toSet());
        var now = LocalDateTime.now();
        var userAccount = AccountHolder.getRequiredAccountInfo().getEmail();
        employeeGroupMemberMapper.update(
                null,
                new UpdateWrapper<EmployeeGroupMember>()
                        .lambda()
                        .eq(EmployeeGroupMember::getGroupId, bo.getGroupId())
                        .in(EmployeeGroupMember::getEmployeeAccount, set)
                        .eq(EmployeeGroupMember::getDeletedFlag, Boolean.FALSE)
                        .set(EmployeeGroupMember::getDeletedFlag, Boolean.TRUE)
                        .set(EmployeeGroupMember::getDeletedBy, userAccount)
                        .set(EmployeeGroupMember::getDeletedDatetime, now)
        );
        return true;
    }

    @Override
    public EmployeeInfoDto employeeAccountInfo(String email) {
        var mEmployee = msasManager.findEmployee(email);
        if (mEmployee == null) {
            return null;
        }
        var m = msasManager.findAccountMetadata(email);
        var rm = msasManager.findRolesMetadata()
                .stream()
                .collect(Collectors.toMap(
                        Role::getCode,
                        i -> i
                ));
        var dto = new EmployeeInfoDto();
        dto.setEmail(mEmployee.getEmail());
        dto.setName(mEmployee.getCn());
        dto.setJobNumber(mEmployee.getEmployeeNumber());
        dto.setPositionName(mEmployee.getTitle());
        dto.setDepartmentName(mEmployee.getDepartmentName());
        setRoleNameJoin(dto, m, rm);
        dto.setNameAndEmail(
                (StringUtils.hasText(dto.getName()) ? dto.getName() : "")
                        + "(" + dto.getEmail() + ")"
        );
        return dto;
    }

    private void setRoleNameJoin(SetRoleNameJoin dto, AccountResourceDto m, Map<String, Role> rm) {
        if (m != null) {
            dto.setRoleNameJoin(
                    m.getRoles() == null ? "" : m.getRoles()
                            .stream()
                            .map(rm::get)
                            .filter(Objects::nonNull)
                            .map(Role::getName)
                            .filter(StringUtils::hasText)
                            .collect(Collectors.joining(","))
            );
        } else {
            dto.setRoleNameJoin("");
        }
    }

    @Override
    public EmployeeGroupsBean getEmployeeGroups(String email) {
        // 找到归属的所有用户组
        var employeeGroupIdSet = employeeGroupMemberMapper.selectList(new QueryWrapper<EmployeeGroupMember>()
                .lambda()
                .eq(EmployeeGroupMember::getEmployeeAccount, email)
                .eq(EmployeeGroupMember::getDeletedFlag, Boolean.FALSE)
        ).stream().map(EmployeeGroupMember::getGroupId).collect(Collectors.toSet());
        if (employeeGroupIdSet.isEmpty()) {
            return noEmployeeGroups();
        }
        // 去除已经删除的用户组（可能只删除了用户组但是没有删除关联）
        employeeGroupIdSet = employeeGroupMapper.selectList(new QueryWrapper<EmployeeGroup>()
                .lambda()
                .in(EmployeeGroup::getId, employeeGroupIdSet)
                .eq(EmployeeGroup::getDeletedFlag, Boolean.FALSE)
        ).stream().filter(i -> !i.getDeletedFlag()).map(EmployeeGroup::getId).collect(Collectors.toSet());
        if (employeeGroupIdSet.isEmpty()) {
            return noEmployeeGroups();
        }
        // 找到这些用户组的学校
        var groupSchools = employeeGroupSchoolMapper.selectList(new QueryWrapper<EmployeeGroupSchool>()
                .lambda()
                .in(EmployeeGroupSchool::getGroupId, employeeGroupIdSet)
                .eq(EmployeeGroupSchool::getDeletedFlag, Boolean.FALSE)
        ).stream().collect(Collectors.groupingBy(EmployeeGroupSchool::getGroupId));
        // 找到这些用户组的学科
        var groupSubjects = employeeGroupSubjectMapper.selectList(new QueryWrapper<EmployeeGroupSubject>()
                .lambda()
                .in(EmployeeGroupSubject::getGroupId, employeeGroupIdSet)
                .eq(EmployeeGroupSubject::getDeletedFlag, Boolean.FALSE)
        ).stream().collect(Collectors.groupingBy(EmployeeGroupSubject::getGroupId));
        // 将数据归类并且返回
        return new EmployeeGroupsBean(employeeGroupIdSet.stream().map(i -> new EmployeeGroupBean(
                groupSchools.getOrDefault(i, new ArrayList<>()).stream().map(EmployeeGroupSchool::getSchoolCode).toList(),
                groupSubjects.getOrDefault(i, new ArrayList<>()).stream().map(EmployeeGroupSubject::getSubjectId).toList()
        )).filter(
                // 去除学校以及学科为空的用户组，这些用户组没有意义
                i -> !i.getSchoolCodeList().isEmpty() && !i.getSubjectIdList().isEmpty()
        ).toList());
    }

    private EmployeeGroupsBean noEmployeeGroups() {
        return new EmployeeGroupsBean(List.of());
    }

}
